package classes;

import java.applet.Applet;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.HeadlessException;
import java.awt.Image;
import java.util.Random;

import javax.swing.JApplet;

public class GameApplet extends Applet implements Runnable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2262982116844695523L;

	private int radius = 50;
	private boolean isStopped= true;
	private Image dbImage;
	private Graphics dbg;
	private Graphics g;
	private Player player;
	private Ball ball1;
	private Ball ball2;
	private Ball bonusBall;
	private static final int bonusThreshold=5;
	private int ballCount;
	private String livesStr= "lives: ";
	private String scoreStr= "Score: ";

	// init - method is called the first time you enter the HTML site with the applet
	public void init() { 
		this.setPreferredSize(new Dimension (500,500));
		this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		player=null;
		ball1=null;
		ball2=null;
		bonusBall=null;
		ballCount=0;
		player = new Player ("lalal",3);
		ball1= new Ball (radius,Color.red,this.getWidth()/2,this.getHeight()/2);
		ball2= new Ball (radius,Color.blue,this.getWidth()/2,this.getHeight()/2);


	}

	// start - method is called every time you enter the HTML - site with the applet
	public void start() {
		// define a new thread
		Thread th = new Thread (this);
		// start this thread
		th.start ();

	}

	// stop - method is called if you leave the site with the applet
	public void stop() { }

	// destroy method is called if you leave the page finally (e. g. closing browser)
	public void destroy (){ }

	/** paint - method allows you to paint into your applet. This method is called e.g. if you move your browser window or if you call repaint() */
	public void paint (Graphics g) { 
		// set color
		//		g.setColor(Color.white);
		//		g.fillRect(0, 0, this.getWidth(), this.getHeight());


		// paint a filled colored circle
		g.setClip(0, 0, this.getWidth(), this.getHeight());
		if (!isStopped){
			g.setColor(Color.black);
			g.drawString(scoreStr+player.getScore(),5, 10);
			g.drawString (livesStr+player.getLives(),this.getWidth()-(g.getFontMetrics(g.getFont()).stringWidth(livesStr)+20),10);
			if(ball1!=null){
				g.setColor(ball1.getColor());
				g.fillOval(ball1.getPosX(), ball1.getPosY(), ball1.getRadius()/2, ball1.getRadius()/2);

			}
			if(ball2!=null){
				g.setColor(ball2.getColor());
				g.fillOval(ball2.getPosX(), ball2.getPosY(), ball2.getRadius()/2, ball2.getRadius()/2);

			}
			if(bonusBall!=null){
				g.setColor(bonusBall.getColor());
				g.fillOval(bonusBall.getPosX(), bonusBall.getPosY(), bonusBall.getRadius()/2, bonusBall.getRadius()/2);

			}
		}else {
			g.drawString("DOUBLE CLICK THE SCREEN TO PLAY!!", this.getWidth()/2-100, this.getHeight()/2);
		}
	}
	public void update(){

		g=this.getGraphics();
		// initialize buffer
		if (dbImage == null)
		{

			dbImage = createImage (this.getSize().width, this.getSize().height);
			dbg = dbImage.getGraphics ();

		}

		// clear screen in background
		dbg.setColor (getBackground ());
		dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

		// draw elements in background
		dbg.setColor (getForeground());
		paint (dbg);

		// draw image on the screen
		g.drawImage (dbImage, 0, 0, this);
		if (!isStopped && player.getLives()>=0){
			updateBalls();

		}else {
			if (player.getLives()<0)
				isStopped=true;
		}


	}
	// Method to handle mouse down events
	//	public boolean keyDown (Event e, int key){
	//		switch (key) {
	//		case Event.DOWN:
	//			y_speed=1;
	//			
	//			break;
	//		case Event.UP:
	//			y_speed=-1;
	//			break;
	//		case Event.RIGHT:
	//			x_speed=1;
	//			break;
	//		case Event.LEFT:
	//			x_speed=-1;
	//			break;
	//		default:
	//			break;
	//		}
	//		return true;
	//	}
	public void updateBalls (){
		if (isBallOut(ball1)){
			player.loseLife();
			ball1=null;
			ball1= new Ball (radius,Color.red,this.getWidth()/2,this.getHeight()/2);
		}else {
			ball1.move();
		}
		if (isBallOut(ball2)){
			player.loseLife();
			ball2=null;
			ball2= new Ball (radius,Color.blue,this.getWidth()/2,this.getHeight()/2);
		}else {
			ball2.move();
		}
		if (bonusBall!=null){
			if (isBallOut(bonusBall)){
				
				bonusBall=null;
				ballCount=0;

			}else {
				bonusBall.move();
			}
		}else {
			if (ballCount==bonusThreshold){
				makeBonusBall();
			}
		}
	}
	public void makeBonusBall(){
		Random random =new Random();
		bonusBall = new Ball (radius/2,Color.green,this.getWidth()/2,this.getHeight()/2,8*(random.nextInt()%2),1*(random.nextInt()%2));

	}
	public boolean mouseDown (Event e, int x, int y)
	{
		if (!isStopped ){

			checkHit(x,y);
		}else
		{
			if (e.clickCount==2){
				isStopped=false;
				init();
			}
		}
		return true; 

	} 
	public void checkHit(int hitX, int hitY){

		double x,y,distance;
		//check if the guy hit the first ball
		x= hitX - ball1.getPosX();
		y = hitY - ball1.getPosY();
		distance = Math.sqrt((x*x+y*y));
		if (distance<=ball1.getRadius()){
			player.addScore(Score.BALL);
			ballCount++;
			ball1=null;
			ball1= new Ball (radius,Color.red,this.getWidth()/2,this.getHeight()/2);
		}
		x= hitX - ball2.getPosX();
		y = hitY - ball2.getPosY();
		distance = Math.sqrt((x*x+y*y));
		if (distance<=ball2.getRadius()){
			player.addScore(Score.BALL);
			ballCount++;
			ball2=null;
			ball2= new Ball (radius,Color.blue,this.getWidth()/2,this.getHeight()/2);

		}
		if (bonusBall!=null){
			x= hitX - bonusBall.getPosX();
			y = hitY - bonusBall.getPosY();
			distance = Math.sqrt((x*x+y*y));
			if (distance<=bonusBall.getRadius()){
				player.addScore(Score.BONUSBALL);
				ballCount=0;
				bonusBall=null;

			}
		}
	}
	public boolean isBallOut (Ball aBall){

		return (aBall.getPosY()-aBall.getRadius())>this.getHeight()||
		(aBall.getPosY()+aBall.getRadius())<0||
		(aBall.getPosX()-aBall.getRadius())>this.getWidth()||
		(aBall.getPosX()+aBall.getRadius())<0;

	}
	public void run ()
	{

		// lower ThreadPriority
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

		// run a long while (true) this means in our case "always"
		while (true)
		{
			// repaint the applet
			repaint();
			update();
			try
			{
				// Stop thread for 20 milliseconds
				Thread.sleep (20);
			}
			catch (InterruptedException ex)
			{
				// do nothing
			}

			// set ThreadPriority to maximum value
			Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		} 

	} 
}
